package jp.chiheisen.common;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

/**
 * リソースファイルを読み込むためストリームです。<br>
 * ここでの「リソースファイル」とは、Jar 内のファイル、またはカレントパスにあるファイルです。<br>
 * (このクラスは、jar にする前後でファイルを同じように扱うためのものです)
 * 
 * @author YujiYamamoto
 * @since 1.0
 */
public class ResourceInputStream extends InputStream {
	/** 移譲するストリーム */
	private final InputStream in;

	/**
	 * リソースファイルを読み込むストリームを作成します。<br>
	 * リソースファイルの探索順序は以下の通りです。
	 * <ol>
	 * <li>この ResourceInputStream クラスが存在する Jar 内</li>
	 * <li>カレントパス</li>
	 * </ol>
	 * このクラスとリソースファイルが一つの Jar にまとめられている場合は、このコンストラクタを使用してください。
	 * 
	 * @param file ファイル名
	 * @throws java.io.FileNotFoundException ファイルが見つからなかったとき
	 */
	public ResourceInputStream(String file) throws FileNotFoundException{
		this(file, ResourceInputStream.class);
	}

	/**
	 * リソースファイルを読み込むストリームを作成します。<br>
	 * リソースファイルの探索順序は以下の通りです。
	 * <ol>
	 * <li>指定のクラスが存在する Jar 内</li>
	 * <li>カレントパス</li>
	 * </ol>
	 * 
	 * @param file ファイル名
	 * @param clazz リソースファイルと同じ Jar 内にあるクラス 
	 * @throws java.io.FileNotFoundException ファイルが見つからなかったとき
	 */
	public ResourceInputStream(String file, Class<?> clazz) throws FileNotFoundException{
		ClassLoader loader = clazz.getClassLoader();			
		InputStream stream = loader.getResourceAsStream(file);
		if(stream == null){
			stream = new FileInputStream(file);
		}
		
		this.in = stream;
	}

	@Override
    public int read() throws IOException{
    	return in.read();
    }

	@Override
    public int read(byte b[]) throws IOException {
        return in.read(b);
    }

	@Override
    public int read(byte b[], int off, int len) throws IOException {
    	return in.read(b, off, len);
    }

	@Override
    public long skip(long n) throws IOException {
    	return in.skip(n);
    }

	@Override
    public int available() throws IOException {
        return in.available();
    }

	@Override
    public void close() throws IOException {
    	in.close();
    }

	@Override
    public void mark(int readlimit) {
    	in.mark(readlimit);
    }

	@Override
    public void reset() throws IOException {
       in.reset();
    }

	@Override
    public boolean markSupported() {
        return in.markSupported();
    }
}
